﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections.Specialized;
using System.Data;
using System.Drawing;
using KpiConfigProject.ChildForm;

namespace KpiConfigProject.Controls
{
    [Serializable]
    public partial class DataGridViewEx : DataGridView
    {
        [NonSerialized]
        private List<DataRowView> _AddRows;
        public List<DataRowView> AddRows
        {
            get { return _AddRows; }
        }

        [NonSerialized]
        private List<DataRowView> _DelRows;
        public List<DataRowView> DelRows
        {
            get { return _DelRows; }
        }

        [NonSerialized]
        private List<DataRowView> _ModRows;

        public List<DataRowView> ModRows
        {
            get { return _ModRows; }
        }

        [NonSerialized]
        private string _tablePrimarykey = "";

        private GridSearchFrm searchFrm;
        private string searchText = "";
        /// <summary>
        /// 
        /// </summary>

        public string TablePrimarykey
        {
            get
            {
                if (_tablePrimarykey == "")
                {
                    if (this.DataSource == null || !typeof(DataView).IsInstanceOfType(this.DataSource))
                        return "";
                    DataView dataView = (DataView)this.DataSource;
                    foreach (DataColumn column in dataView.Table.Columns)
                    {
                        if (column.AutoIncrement)
                        {
                            _tablePrimarykey = column.ColumnName;
                            break;
                        }
                    }
                }
                return _tablePrimarykey;
            }
            set { _tablePrimarykey = value; }
        }

        private bool _IsEditStyle = true;
        [DefaultValue(true)]
        public bool IsEditStyle
        {
            get { return _IsEditStyle; }
            set { _IsEditStyle = value; }
        }

        public DataGridViewEx()
        {
            InitializeComponent();
            //this.CellEndEdit += new DataGridViewCellEventHandler(DataGridViewEx_CellEndEdit);
            this.CellValueChanged += new DataGridViewCellEventHandler(DataGridViewEx_CellValueChanged);
            this.RowHeadersWidth = 20;
            this.AllowUserToResizeRows = false;
            this.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.DisableResizing;
            _AddRows = new List<DataRowView>();
            _DelRows = new List<DataRowView>();
            _ModRows = new List<DataRowView>();
        }

        public void ClearRowData()
        {
            _AddRows.Clear();
            _ModRows.Clear();
            _DelRows.Clear();
        }

        #region 编辑时的颜色变化

        void DataGridViewEx_CellValueChanged(object sender, DataGridViewCellEventArgs e)
        {
            DataRowView rowView = (DataRowView)this.Rows[e.RowIndex].DataBoundItem;
            rowView.EndEdit();
            if (rowView.Row.RowState != DataRowState.Modified)
                return;
            if (_AddRows.Contains(rowView))
                return;
            if (_DelRows.Contains(rowView))
                return;
            if (!_ModRows.Contains(rowView))
                _ModRows.Add((rowView));
            if (_IsEditStyle)
            {
                this.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.Gainsboro;
                Font cellFont = this.Rows[e.RowIndex].Cells[e.ColumnIndex].InheritedStyle.Font;
                this.Rows[e.RowIndex].Cells[e.ColumnIndex].InheritedStyle.Font = new Font(cellFont.FontFamily,
                                                                                          cellFont.Size + 5,
                                                                                          FontStyle.Bold);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="e"></param>
        protected override void OnKeyDown(KeyEventArgs e)
        {
            base.OnKeyDown(e);
            if (e.Control && e.KeyCode == Keys.V)
            {
                if (Clipboard.ContainsText())
                {
                    string clipboardText = Clipboard.GetText();
                    InitClipBoardData(clipboardText);
                }
            }
            else if (e.KeyCode == Keys.Delete)
            {
                if (this.SelectedRows.Count <= 0)
                    return;
                DeleteRows();
            }
            else if (e.Control && e.KeyCode == Keys.F)
            {
                if (searchFrm != null)
                    searchFrm.Dispose();
                searchFrm = new GridSearchFrm();
                searchFrm.SearchText = searchText;
                searchFrm.SearchTextChanged += new EventHandler(searchFrm_SearchTextChanged);
                searchFrm.Show();
            }
        }
        #endregion


        public void DeleteRows()
        {
            List<int> rowIndexs = new List<int>();
            foreach (DataGridViewCell cell in this.SelectedCells)
            {
                if (!rowIndexs.Contains(cell.RowIndex))
                    rowIndexs.Add(cell.RowIndex);
            }
            for (int i = rowIndexs.Count - 1; i >= 0; i--)
            {
                DataGridViewRow row = this.Rows[rowIndexs[i]];
                DataRowView rowView = (DataRowView)row.DataBoundItem;
                if (rowView.IsNew || AddRows.Contains(rowView))
                {
                    if (AddRows.Contains(rowView))
                        AddRows.Remove(rowView);
                    rowView.Delete();
                    continue;
                }
                if (!DelRows.Contains(rowView))
                    DelRows.Add(rowView);
                row.DefaultCellStyle.BackColor = Color.HotPink;
            }
            rowIndexs.Clear();
            rowIndexs = null;
        }

        public void AddNewRow()
        {
            if (this.DataSource == null || !typeof(DataView).IsInstanceOfType(this.DataSource))
                return;
            DataView view = (DataView)this.DataSource;
            DataRowView dataRow = view.AddNew();
            _AddRows.Add(dataRow);
        }
        /// <summary>
        /// 还原选中的记录
        /// </summary>
        internal void RestoreRows()
        {
            List<int> rowIndexs = new List<int>();
            foreach (DataGridViewCell cell in this.SelectedCells)
            {
                if (!rowIndexs.Contains(cell.RowIndex))
                    rowIndexs.Add(cell.RowIndex);
            }
            foreach (int rowIndex in rowIndexs)
            {
                DataGridViewRow row = this.Rows[rowIndex];
                DataRowView rowView = (DataRowView)row.DataBoundItem;
                rowView.Row.RejectChanges();
                row.DefaultCellStyle.BackColor = Color.White;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        internal void RestoreAllRows()
        {
            foreach (DataGridViewRow row in this.Rows)
            {
                DataRowView rowView = (DataRowView)row.DataBoundItem;
                rowView.Row.RejectChanges();
                row.DefaultCellStyle.BackColor = Color.White;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="clipboardText"></param>
        private void InitClipBoardData(string clipboardText)
        {
            searchText = clipboardText;
            if (this.DataSource == null || !typeof(DataView).IsInstanceOfType(this.DataSource))
                return;
            this.BeginEdit(false);
            try
            {
                DataView dataView = (DataView)this.DataSource;
                string[] textRows = clipboardText.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
                DataGridViewSelectedCellCollection cellCollection = this.SelectedCells;
                int columnIndex = cellCollection[0].ColumnIndex;
                int rowIndex = cellCollection[0].RowIndex;

                DataGridViewRow selectRow = this.Rows[rowIndex];
                foreach (string textRow in textRows)
                {
                    string[] textColumns = textRow.Split(new string[] { "\t" }, StringSplitOptions.RemoveEmptyEntries);
                    for (int i = 0; i < textColumns.Count(); i++)
                    {
                        if (columnIndex + i >= this.Columns.Count)
                            break;
                        DataGridViewCell curCell = selectRow.Cells[columnIndex + i];
                        Type columnType = curCell.ValueType;
                        string textColumn = textColumns[i];
                        if (columnType.Equals(typeof(int)))
                        {
                            int intValue;
                            if (int.TryParse(textColumn, out intValue))
                            {
                                curCell.Value = intValue;
                            }
                        }
                        else if (columnType.Equals(typeof(string)))
                        {
                            curCell.Value = textColumn;
                        }
                        else if (columnType.Equals(typeof(DateTime)))
                        {
                            DateTime time = DateTime.Now;
                            if (DateTime.TryParse(textColumn, out time))
                            {
                                curCell.Value = time;
                            }
                        }
                    }
                    rowIndex += 1;
                    if (rowIndex >= this.Rows.Count)
                    {
                        AddNewRow();
                    }
                    selectRow = this.Rows[rowIndex];
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
            this.EndEdit();
        }
        /// <summary>
        /// 
        /// </summary>
        public void RejectChanges()
        {
            DataView dataView = (DataView)this.DataSource;
            dataView.Table.RejectChanges();
        }
        /// <summary>
        /// 全局搜索
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void searchFrm_SearchTextChanged(object sender, EventArgs e)
        {
            searchText = sender.ToString();
            FilterGridData(searchText);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        public List<DataGridViewRow> FilterGridData(string text)
        {
            return FilterGridData("", text);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="fieldName"></param>
        /// <param name="text"></param>
        /// <returns></returns>
        public List<DataGridViewRow> FilterGridData(string fieldName, string text)
        {
            searchText = text;
            List<DataGridViewRow> gridViewRows = new List<DataGridViewRow>();
            this.BindingContext[this.DataSource].SuspendBinding();
            foreach (DataGridViewRow row in this.Rows)
            {
                if (searchText == "")
                    row.Visible = true;
                else
                {
                    bool isSearch = false;
                    if (fieldName == null || fieldName == "" || !this.Columns.Contains(fieldName))
                        foreach (DataGridViewCell cell in row.Cells)
                        {
                            if (cell.Value.ToString().ToLower().Contains(text.ToLower()))
                            {
                                isSearch = true;
                                gridViewRows.Add(row);
                                break;
                            }
                        }
                    else
                    {
                        if (row.Cells[fieldName].Value.ToString().ToLower().Contains(text.ToLower()))
                        {
                            isSearch = true;
                            gridViewRows.Add(row);
                        }
                    }
                    if (isSearch)
                        row.Visible = true;
                    else
                        row.Visible = false;
                }
            }
            this.BindingContext[this.DataSource].ResumeBinding();
            return gridViewRows;
        }
    }
}
